/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package classes;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;

/**
 *
 * @author Diogo
 */
public class EncryptedFile {

    //  public static final int AES_Key_Size = 256;
    Cipher pkCipher, aesCipher;
    byte[] aesKey;
    SecretKeySpec aeskeySpec;
    SecureSharing ss;
    ArrayList<String> usersDestinatarios = new ArrayList<>();

    public EncryptedFile(ArrayList<String> usersDestinatarios, SecureSharing ss) throws NoSuchAlgorithmException, NoSuchPaddingException {
        //this.usersDestinatarios = (SecureSharing[])usersDestinatarios;
        // create RSA public key cipher
        this.usersDestinatarios = usersDestinatarios;
        pkCipher = Cipher.getInstance("RSA");
        // create AES shared key cipher
        aesCipher = Cipher.getInstance("AES");
        this.ss = ss;
    }

    private ArrayList<X509Certificate> getCertUsersDestinatarios() throws CertificateException, FileNotFoundException {
        ArrayList<X509Certificate> certsUsersDestinatarios = new ArrayList<>();

        X509Certificate c;
        FileInputStream cert;
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        File certificateFile;
        for (int i = 0; i < usersDestinatarios.size(); i++) {
            certificateFile = new File(ss.getPath() + "//Certificados/" + ss.getUserCertificate(usersDestinatarios.get(i)));
            cert = new FileInputStream(certificateFile);
            c = (X509Certificate) cf.generateCertificate(cert);
            certsUsersDestinatarios.add(c);
        }
        return certsUsersDestinatarios;
    }

    public void encrypt(File in, File out) throws IOException, InvalidKeyException, CertificateException {
        System.out.println("estou aqui a tentar fazer alguma coisa");
        X509Certificate c;
        FileInputStream cert;
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        File certificateFile;

        for (int i = 0; i < usersDestinatarios.size(); i++) {
            certificateFile = new File(ss.getPath() + "//Certificados/" + ss.getUserCertificate(usersDestinatarios.get(0)));
            cert = new FileInputStream(certificateFile);
            c = (X509Certificate) cf.generateCertificate(cert);
            pkCipher.init(Cipher.ENCRYPT_MODE, c.getPublicKey());
            pkCipher.init(Cipher.ENCRYPT_MODE, getCertUsersDestinatarios().get(i).getPublicKey()); //ALTERAR
        }
        FileInputStream is = new FileInputStream(in);
        CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), pkCipher);

        copy(is, os);

        os.close();
    }

    public void decrypt(File in, File out) throws IOException, InvalidKeyException, CertificateException {
        JPasswordField pwd = new JPasswordField(50);
        int action = JOptionPane.showConfirmDialog(null, pwd, "Enter Password", JOptionPane.OK_CANCEL_OPTION);
        if (action < 0) {
            JOptionPane.showMessageDialog(null, "Cancel, X or escape key selected");
        }
        PrivateKey pk = getPrivateKey(ss.getPath() + "//Certificados/" + ss.getUserCertificate(usersDestinatarios.get(0)), pwd.getPassword());
        pkCipher.init(Cipher.DECRYPT_MODE, pk);

        CipherInputStream is = new CipherInputStream(new FileInputStream(in), pkCipher);
        FileOutputStream os = new FileOutputStream(out);

        copy(is, os);

        is.close();
        os.close();
    }

    private void copy(InputStream is, OutputStream os) throws IOException {
        int i;
        byte[] b = new byte[1024];
        while ((i = is.read(b)) != -1) {
            os.write(b, 0, i);
        }
    }

    
     private PrivateKey getPrivateKey(String pathCertificado, char[] password) {
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(pathCertificado);
            ks.load(fis, password);
            fis.close();
            System.out.println("keystore type=" + ks.getType());
            Enumeration enumas = ks.aliases();
            String keyAlias = null;
            if (enumas.hasMoreElements())// we are readin just one certificate.  
            {
                keyAlias = (String) enumas.nextElement();
            }
            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, password);

            return prikey;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
